package utils

import (
	"fmt"
	"github.com/spf13/viper"
)

type AppConfig struct {
	Mode          string
	Port          int
	ReadTimeOut   int
	WriteTimeOut  int
	MaxUploadSize int
	Url           string
}

type SubDatabaseConfig struct {
	Type   string
	Host   string
	Port   int
	User   string
	Passwd string
	Dbname string
	Prefix string
	Debug  bool
}

type ConnectionPoolConfig struct {
	MaxIdleConnection int
	MaxOpenConnection int
	MaxLifeTime       int
}

type DatabaseConfig struct {
	Master SubDatabaseConfig
	Pool   ConnectionPoolConfig
}

type RedisConfig struct {
	Host              string
	Passwd            string
	Port              int
	DB                int
	Timeout           int
	PoolSize          int
	MinIdleConnection int
	DialTimeout       int
	ReadTimeout       int
	WriteTimeout      int
	PoolTimeout       int
}

type LoggerConfig struct {
	Path  string
	Level uint
}

type VerificationConfig struct {
	Dev           bool
	Debug         bool
	Server        string
	MerchantList  []int
	AesSecret     string
	AesIv         string
	SignSecret    string
	SignCheck     bool
	UniqueCheck   bool
	TimeCheck     bool
	MinValueLimit float64
}

type Consumer struct {
	Mode    string
	Limit   int
	Prefix  string
	ListKey string
	Channel string
}

type FourCheckFactorConfig struct {
	Host   string
	Secret string
}

type OssConfig struct {
	Bucket   string
	Endpoint string
}

type AliYunConfig struct {
	AccessKeyId     string
	AccessSecret    string
	FourCheckFactor FourCheckFactorConfig
	Oss             OssConfig
}

type UploadConfig struct {
	Path     string
	MaxSize  int64
	AllowExt []string
}

type DownloadConfig struct {
	Path     string
	MaxSize  int64
	AllowExt []string
}

type Config struct {
	App          AppConfig
	Database     DatabaseConfig
	Redis        RedisConfig
	Logger       LoggerConfig
	Verification VerificationConfig
	Consumer     Consumer
	AliYun       AliYunConfig
	Upload       UploadConfig
	Download     DownloadConfig
}

var Configuration *Config

func init() {
	viper.SetConfigFile("yaml")
	viper.SetConfigFile("./config/config.yaml")
	err := viper.ReadInConfig()
	if err != nil {
		panic(fmt.Sprintf("打不到配置文件：%v", err.Error()))
	}
	err = viper.Unmarshal(&Configuration)
	if err != nil {
		panic(fmt.Sprintf("解析配置文件失败：%v", err.Error()))
	}
}

func GetConfig() *Config {
	return Configuration
}

func SetConfig(callable func(config *Config)) {
	callable(Configuration)
}

func Viper(name string) *viper.Viper {
	return viper.Sub(name)
}
